/*
 * Copyright 2010 Michael Nitsche
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.mnit.basis.sys.thread;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import de.mnit.basis.fehler.Fehler;

/**
 * @author Michael Nitsche
 *
 * TODO finally!!!
 */
public class StreamPumpe {

	public static final int BLOCKGROESSE=1024;


	//ACHTUNG kein synchronized, da sonst nur immer einer kopieren könnnte wenn nicht parallel.
	public static Schranke verbinde(InputStream quelle, OutputStream ziel, boolean parallel) {
		return verbinde(quelle,ziel,parallel,true);
	}

	public static Schranke verbinde(InputStream quelle, OutputStream ziel, boolean parallel, boolean ziel_schliessen) {
		return verbinde(quelle,ziel,parallel,true,BLOCKGROESSE);
	}

	public static Schranke verbinde(final InputStream quelle, final OutputStream ziel, final boolean parallel, final boolean ziel_schliessen, final int block) {
		final Schranke schranke = parallel ? new Schranke(false) : null;
		Runnable run = new Runnable() {
			public void run() {
				try {
					BufferedInputStream  bis = new BufferedInputStream (quelle);
					BufferedOutputStream bos = new BufferedOutputStream(ziel);
					byte[] ba = new byte[block];
					for(int len=0; (len=bis.read()) > -1; ) {
						bos.write(len);
						while((len=bis.read(ba))==block)
							bos.write(ba);
						if(len>0)
							bos.write(ba, 0, len);
					}
					bis.close();
					if(ziel_schliessen)
						bos.close();
					else
						bos.flush();
					if(parallel)
						schranke.oeffnen();
				}
				catch(Throwable t) {
					Fehler.zeig(t);
				}
			}
		};
		if(parallel)
			new Thread(run).start(); else run.run();
		return schranke;
	}

}
